package com.zttek.photosShareProject.modules.service.share.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.zttek.photosShareProject.common.json.NoticeVO;
import com.zttek.photosShareProject.common.json.VO;
import com.zttek.photosShareProject.modules.mapper.NoticeMapper;
import com.zttek.photosShareProject.modules.mapper.NoticeReadMapper;
import com.zttek.photosShareProject.modules.model.Notice;
import com.zttek.photosShareProject.modules.model.NoticeRead;
import com.zttek.photosShareProject.modules.service.share.INoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Y
 * Date: 2017-09-19
 * Time: 12:27
 */
@Service
public class NoticeService implements INoticeService {

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private NoticeReadMapper readMapper;

    @Transactional
    @Override
    public Notice newNotice(String page, boolean publish) throws Exception {
        Notice notice = new Notice();
        notice.setPage(page);
        if (publish){
            notice.setPublishTime(new Date());
        }
        noticeMapper.insert(notice);
        return notice;
    }

    @Override
    public Notice selectNotice(Integer noticeId) throws Exception {
        return noticeMapper.selectById(noticeId);
    }

    @Override
    public Page<Notice> selectNoticePage(Page<Notice> page, Long userId) throws Exception {
        EntityWrapper<Notice> ew = new EntityWrapper<>();
        ew.where("valid=1");
        if (userId != null) {
            ew.and("publish_time is not null");
            List<Integer> deleteList = getUserDeleteList(userId);
            if (deleteList.size() > 0) {
                ew.notIn("id", deleteList);
            }
        }
//        List<Share> list = shareSelectPage(page, ew);
        List<Notice> list = noticeMapper.selectPage(page, ew);
        page.setRecords(list);
        return page;
    }

    @Override
    public Page<Notice> selectAllNoticePage(Page<Notice> page) throws Exception {
        EntityWrapper<Notice> ew = new EntityWrapper<>();
        ew.where("valid=1").orderBy("createTime",false).orderBy("id");
        page.setRecords(noticeMapper.selectPage(page,ew));
        return page;
    }

    @Override
    public Page<Notice> selectLikeNoticePage(Page<Notice> page, String searchValue) throws Exception {
        EntityWrapper<Notice> ew = new EntityWrapper<>();
        if (searchValue.trim().length()==0&&searchValue.trim().equals("")){
            ew.where("valid=1").orderBy("createTime");
        }else{
            ew.where("valid=1").like("page",searchValue).orderBy("createTime",false);
        }
        page.setRecords(noticeMapper.selectPage(page,ew));
        return page;
    }

    @Override
    public void editNotice(Notice notice) throws Exception {
        noticeMapper.updateById(notice);
    }

    @Transactional
    @Override
    public void publish(Integer noticeId) throws Exception {
        Notice notice = noticeMapper.selectById(noticeId);
        notice.setPublishTime(new Date());
        noticeMapper.updateById(notice);
    }

    @Transactional
    @Override
    public void delete(Integer noticeId) throws Exception {
        Notice notice = noticeMapper.selectById(noticeId);
        notice.setValid(0);
        noticeMapper.updateById(notice);
    }

    @Override
    public List<Integer> getUserDeleteList(Long userId) throws Exception {
        NoticeRead noticeRead = selectNoticeRead(userId);
        return VO.divideIntegerIdList(noticeRead.getDeleteList());
    }

    @Override
    public List<Integer> getUserReadList(Long userId) throws Exception {
        NoticeRead noticeRead = selectNoticeRead(userId);
        return VO.divideIntegerIdList(noticeRead.getReadList());
    }

    @Override
    public NoticeRead selectNoticeRead(Long userId) throws Exception {
        EntityWrapper<NoticeRead> ew = new EntityWrapper<>();
        ew.where("user_id = {0}", userId);
        List<NoticeRead> list = readMapper.selectList(ew);
        NoticeRead noticeRead;
        if (list.size() == 0)
            noticeRead = newUserRead(userId);
        else
            noticeRead = list.get(0);
        return noticeRead;
    }

    @Transactional
    @Override
    public NoticeRead newUserRead(Long userId) throws Exception {
        NoticeRead noticeRead = new NoticeRead();
        noticeRead.setUserId(userId);
        readMapper.insert(noticeRead);
        return noticeRead;
    }

    @Transactional
    @Override
    public void readNotice(Integer noticeId, Long userId) throws Exception {
        NoticeRead noticeRead = selectNoticeRead(userId);
        List<Integer> il = VO.divideIntegerIdList(noticeRead.getReadList());
        if (il.contains(noticeId))
            return;
        else
            il.add(noticeId);
        noticeRead.setReadList(VO.mergeIds(il));
        readMapper.updateById(noticeRead);
    }

    @Transactional
    @Override
    public void deleteNotice(Integer noticeId, Long userId) throws Exception {
        NoticeRead noticeRead = selectNoticeRead(userId);
        List<Integer> il = VO.divideIntegerIdList(noticeRead.getDeleteList());
        if (il.contains(noticeId))
            return;
        else
            il.add(noticeId);
        noticeRead.setDeleteList(VO.mergeIds(il));
        readMapper.updateById(noticeRead);
    }

    @Override
    public NoticeVO notice2VO(Notice notice, Long userId) throws Exception {
        List<Integer> readList = getUserReadList(userId);
        return notice2VO(notice, readList.contains(notice.getId()));
    }

    private NoticeVO notice2VO(Notice notice, boolean read) throws Exception {
        NoticeVO noticeVO = new NoticeVO();
        noticeVO.setNoticeId(notice.getId());
        noticeVO.setRead(read);
        return noticeVO;
    }

    @Override
    public List<NoticeVO> notice2VO(List<Notice> notices, Long userId) throws Exception {
        List<NoticeVO> list = new ArrayList<>();
        List<Integer> readList = getUserReadList(userId);
        for (Notice notice : notices) {
            list.add(notice2VO(notice, readList.contains(notice.getId())));
        }
        return list;
    }
}
